  <!--富文本组件-->
<template>
  <div class="app-container">
    <div class="avatar">
      <!-- 图片上传组件辅助-->
      <a-upload class="quill-upload" :action="action" name="file" :beforeUpload="beforeUpload"
        :customRequest="customRequest">
        <a-button id="upBtn">
          <a-icon type="upload" /> 上传文件
        </a-button>
      </a-upload>
    </div>
    <a-row>
      <div class="edit_container">
        <quill-editor class="editor" v-model="newContent" ref="myQuillEditor" :options="editorOption"
          @change="onEditorChange($event)" @ready="onEditorReady($event)">
        </quill-editor>
      </div>
    </a-row>
  </div>
</template>

<script>
//这里可以导入其他文件（比如：组件，工具js，第三方插件js，json文件，图片文件等等）
//例如：import 《组件名称》 from '《组件路径》';
// 引入自定义配置
import { toolOptions, titleConfig } from "./save";
//引入quillEditor编辑器模块,引入Quill模块
import { quillEditor, Quill } from "vue-quill-editor";
//引入图片缩放插件,需要依赖Quill模块
import ImageResize from "quill-image-resize-module";
//引入图片拖拽插件,需要依赖Quill模块
import { ImageDrop } from "quill-image-drop-module";
// 引入样式文件
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
// 注册组件
Quill.register("modules/imageResize", ImageResize);
Quill.register("modules/imageDrop", ImageDrop);
export default {
  name: "AEditor",
  //import引入的组件需要注入到对象中才能使用
  components: {
    quillEditor,
  },
  model: {
    prop: "content",
    event: "change",
  },
  props: {
    content: {
      type: String,
      default: "",
    },
  },
  data() {
    //这里存放数据
    return {
      uploadList: [],
      action: "/admin_server/file/upload",
      newContent: this.content, // 富文本内容
      // 富文本编辑器配置
      editorOption: {
        placeholder: "请输入内容,或者复制内容到光标处...",
        theme: "snow", // or 'bubble'
        modules: {
          clipboard: {
            // 粘贴版，处理粘贴时候的自带样式
            matchers: [[Node.ELEMENT_NODE, this.handleCustomMatcher]],
          },
          toolbar: {
            container: toolOptions, // 工具栏
            handlers: {
              image: function (value) {
                if (value) {
                  // 绑定上传图片按钮
                  // console.log(document.querySelector("#upBtn"));
                  document.querySelector("#upBtn").click();
                } else {
                  this.quill.format("image", false);
                }
              },
            },
          },
          imageResize: {
            //图片缩放配置
            displayStyles: {
              backgroundColor: "black",
              border: "none",
              color: "white",
            },
            modules: ["Resize", "DisplaySize", "Toolbar"],
          },
          imageDrop: false, //图片拖拽配置,false为开启拖拽,true关闭拖拽1
        },
      },
    };
  },
  //方法集合
  methods: {
    /**
     * 文件上传前校验
     * @param {*} file
     */
    async beforeUpload(file) {
      const isJpgOrPng =
        file.type === "image/jpeg" ||
        file.type === "image/png" ||
        file.type === "image/img" ||
        file.type === "image/jpg";
      if (!isJpgOrPng) {
        this.$message.error("You can only upload JPG file!");
      }
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error("Image must smaller than 2MB!");
      }
      // await this.isSize(file, 345, 150);
      return isJpgOrPng && isLt2M;
    },
    /**
     * 覆盖ant默认上传，自定义上传文件
     * @param {*} info
     */
    customRequest(info) {
      // 获取文件
      const { file } = info;
      this.$request
        .postRequest3(this.action, this.getFormData(file))
        .then((res) => {
          if (res.success) {
            this.insertFile(res);
          }
        });
    },
    /**
     * 获取上传文件参数
     * @param {*} file
     * @return FormData
     */
    getFormData(file) {
      var formData = new FormData();
      formData.append("file", file);
      // formData.append("scale", "1");
      // formData.append("outputQuality", "1");
      return formData;
    },
    /**
     * 复制内容到富文本
     */
    copyContent() {
      let quill = this.$refs.myQuillEditor.quill;
      quill.root.addEventListener(
        "paste",
        (evt) => {
          if (
            evt.clipboardData &&
            evt.clipboardData.files &&
            evt.clipboardData.files.length
          ) {
            evt.preventDefault();
            [].forEach.call(evt.clipboardData.files, (file) => {
              if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
                return;
              }
              this.uploadToServer(file, (res) => {
                // 获取光标内容
                var range = quill.getSelection();
                if (range && res.success) {
                  // 插入
                  this.insertFile(res);
                  //  将光标移动到图片后面
                  this.$refs.myQuillEditor.quill.setSelection(range.index + 1);
                }
              });
            });
          }
        },
        false
      );
    },
    /**
     * 清楚复制内容样式
     * @param {*} node
     * @param {*} Delta
     */
    handleCustomMatcher(node, Delta) {
      // 文字、图片等，从别处复制而来，清除自带样式，转为纯文本
      // console.log("复制");
      let ops = [];
      Delta.ops.forEach((op) => {
        if (op.insert && typeof op.insert === "string") {
          ops.push({
            insert: op.insert,
          });
        }
      });
      Delta.ops = ops;
      return Delta;
    },
    /**
     * 复制文件上传到服务端
     * @param {*} file
     * @param {*} callback
     */
    uploadToServer(file, callback) {
      //调上传接口 换成自己的 不过返回的数据要传入到callback中
      this.$request
        .postRequest3(this.action, this.getFormData(file))
        .then((res) => {
          callback(res);
        });
    },
    /**
     * 根据服务端返回数据插入文件到富文本
     * @param {} res
     */
    insertFile(res) {
      let quill = this.$refs.myQuillEditor.quill;
      // 获取光标所在位置
      let length = quill.getSelection().index;
      // 插入图片  需要替换为自己服务器返回的图片地址
      let imgPath = this.$filePrefix + res.result.uuid;
      quill.insertEmbed(length, "image", imgPath);
      quill.setSelection(length + 1);
    },
    /**
     * 内容改变时
     * @param {*} data
     */
    onEditorChange(data) {
      // console.log("输入：", data);
      this.newContent = data.html
    },
    setNbsp(str) {
      // 替换空格
      // str = str.replace(new RegExp(/( )/g), "&nbsp;");
      // 替换tab键
      // str = str.replace(new RegExp(/(\t)/g), "&nbsp;&nbsp;&nbsp;");
      return str
    },
    /**
     * 组件注册
     * @param {*} editor
     */
    // eslint-disable-next-line no-unused-vars
    onEditorReady(editor) {
      // console.log("回显：", this.content);
      document.querySelector("div.ql-editor").innerHTML = this.newContent;
    },
    /**
     * 富文本内容改变通知父组件
     * @param {*} newval
     */
    // eslint-disable-next-line no-unused-vars
    sendMsg(newval) {
      this.$emit("contentChange", this.newContent);
    },
    /**
     * 设置中文
     */
    setTitleConfig() {
      for (const item of titleConfig) {
        const tip = document.querySelector('.quill-editor ' + item.Choice)
        if (!tip) continue
        tip.setAttribute('title', item.title)
      }
    }
  },
  //监听属性 类似于data概念
  watch: {
    /**
     * 监听内容
     * @param {*} val
     * @param {*} newval
     */
    newContent(newval) {
      // this.sendMsg(newval);
      this.$emit("change", this.setNbsp(newval));
    },
  },
  computed: {
    editor() {
      return this.$refs.myQuillEditor.quillEditor;
    },
  },
  //生命周期 - 创建完成（可以访问当前this实例）
  created() { },
  //生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {
    /**
     * 注册复制行为
     */
    this.copyContent();
    this.$nextTick(() => {
      //为工具栏的所有图标按钮添加鼠标悬停时的文字提示
      // addQuillTitle();
      this.setTitleConfig()
    });
  },
  beforeCreate() { }, //生命周期 - 创建之前
  beforeMount() { }, //生命周期 - 挂载之前
  beforeUpdate() { }, //生命周期 - 更新之前
  updated() { }, //生命周期 - 更新之后
  beforeDestroy() { }, //生命周期 - 销毁之前
  destroyed() { }, //生命周期 - 销毁完成
  activated() { }, //如果页面有keep-alive缓存功能，这个函数会触发
};
</script>

<style>
.avatar {
  display: none;
}

/*.editor 自定义的样式,可以自己控制富文本窗体大小*/
.editor {
  line-height: normal !important;
}

/**设置内容框高度，超过滚动 */
.editor .ql-container {
  height: 500px !important;
}

.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {
  border-color: #ccc;
  height: 150px;
  overflow: auto;
}

/** 设置中文 */
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "字体大小";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]::before {
  content: "12px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
  content: "14px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
  content: "16px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
  content: "18px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
  content: "20px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="24px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="24px"]::before {
  content: "24px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="28px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="28px"]::before {
  content: "28px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="32px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="32px"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="36px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="36px"]::before {
  content: "36px";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "字体"
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimSun"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimSun"]::before {
  content: "SimSun"
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimHei"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimHei"]::before {
  content: "SimHei"
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Microsoft-YaHei"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Microsoft-YaHei"]::before {
  content: "Microsoft-YaHei"
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="KaiTi"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="KaiTi"]::before {
  content: "KaiTi"
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="FangSong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="FangSong"]::before {
  content: "FangSong"
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "标题"
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1"
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2"
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3"
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4"
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5"
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6"
}
</style>